import {Injectable} from "@nestjs/common";
import {JwtService} from "@nestjs/jwt";
import {LoginWebUserDto, RegWebUserDto} from "../user/dto/req-web-user.dto";
import {ResultData} from "../../../common/utils/result";
import * as bcrypt from "bcryptjs";
import {GenerateUUID} from "../../../common/utils";
import {WebUserService} from "../user/web-user.service";
import {StudentEntity} from "../../eduation/student/entities/student.entity";
import {CLIENT_USER_TYPE} from "../../../common/constant";


@Injectable()
export  class WebAuthService {
    constructor(
        private readonly jwtService: JwtService,
        private readonly webUserService: WebUserService,
    ) {}

    createToken(payload:{ uuid:string;userId:number}):string{
        const accessToken = this.jwtService.sign(payload);
        return accessToken;
    }


    /**
     * 登录
     * @param body
     */
    async login(body: LoginWebUserDto){
        const user = await this.webUserService.findByCount(body.account);
        if (!user)  return  ResultData.fail(500,'账号不存在')
        if (!user.loginEnabled) return  ResultData.fail(500,'用户已禁用')
        const isValid = bcrypt.compareSync(body.password + user.salt, user.password);
        if (!isValid) return  ResultData.fail(500,'密码错误')

        const uuid = GenerateUUID();
        const token = this.createToken({uuid :uuid,userId:user.studentId })
        return ResultData.ok({
            token:token
        })
    }

    /**
     * 注册
     * @param body
     */
    async create(body:RegWebUserDto ) {
        // 账户是否存在
        const hasAccount = await this.webUserService.findByFilter({  username:body.username})
        if(hasAccount) return  ResultData.fail(400, '账号名已存在')
        // 手机号是否存在
        const hasPhone = await this.webUserService.findByFilter({  phone:body.phone})
        if(hasPhone) return  ResultData.fail(400, '手机号已存在')
        // 邮箱是否存在
        const hasEmail = await this.webUserService.findByFilter({  email:body.email})
        if(hasEmail) return  ResultData.fail(400, '邮箱已存在')
        // 插
        const entity = new StudentEntity();
        Object.assign(entity,body);
        entity.createTime = new Date();
        entity.salt = bcrypt.genSaltSync(6);
        entity.password = bcrypt.hashSync(body.password + entity.salt, 10);
        entity.userType = CLIENT_USER_TYPE.CUSTOM
        return await  this.webUserService.create(entity);
    }


    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    async parseToken(token: string){
        if (!token) return { payload: null, error: 'invalid' };
        try {
            const cleanToken = token.replace('Bearer ', '');
            const payload = await this.jwtService.verify(cleanToken);
            return { payload };
        } catch (e) {
            if (e.name === 'TokenExpiredError') {
                return { payload: null, error: 'expired' };
            }
            return { payload: null, error: 'invalid' };
        }
    }
}
